const protoLoader = require('@grpc/proto-loader');
const GrpcCore = require('grpc');
const path = require('path');
const fs = require('fs');
const nacosClient = require('./nacosClient');

module.exports = async () => {
  saas.grpcClient = await createClient();
};

async function createClient() {
  const service = {};
  const config = saas.config;
  const protoPath = config.grpcClient.protoPath;
  await getAllServices(path.join(saas.ROOT_PATH, protoPath), config);
  return service;
}

async function getAllServices(protoPath, config) {
  if (!fs.existsSync(protoPath)) {
    throw new Error('no proto file');
  }
  const protoFileList = fs.readdirSync(protoPath);
  const client = await nacosClient();
  for (const protoName of protoFileList) {
    const protoFilePath = path.join(protoPath, protoName);
    const stats = fs.statSync(protoFilePath);
    if (stats.isFile() && path.extname(protoName) === '.proto') {
      const protoObj = await protoLoader.load(protoFilePath, config.grpcClient.loaderOption || {});
      const Rpc = GrpcCore.loadPackageDefinition(protoObj);
      for (const rpcpackage in protoObj) {
        if (typeof Rpc[rpcpackage]!=='function') continue;
        client.subscribe(rpcpackage, hosts => {
          for (const instance of hosts) {
            if (instance.valid) {
              saas.grpcClient[rpcpackage] = new Rpc[rpcpackage](`${instance.ip}:${instance.port}`, GrpcCore.credentials.createInsecure());
              console.log(`[saas-grpc-client] ${rpcpackage} load`);
            }
          }

        });

      }
    }
  }
  console.log('[saas-grpc-client] grpc-client loaded!')
}